﻿// 208 多重背包3.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <deque>
#include <memory.h>

using namespace std;
/*
http://oj.daimayuan.top/course/5/problem/168
有 n种物品要放到一个袋子里，袋子的总容量为 m
，第 i种物品的体积为 vi
，把它放进袋子里会获得 wi的收益，一共有 li个。
问如何选择物品，使得在物品的总体积不超过 m的情况下，获得最大的收益？请求出最大收益。

输入格式
第一行两个整数 n,m。

接下来 n行，每行三个整数 vi,wi,li。

输出格式
一个整数，表示答案。

样例输入
5 10
2 1 2
5 8 2
2 4 5
3 9 2
4 3 2
样例输出
26


2 10
2 4 5
3 9 2




数据规模
对于所有数据，保证 1≤n,m,vi,wi,li≤104。
*/


//int n, m, v, w, t, f[10001],c[10001][2];
//
//int main()
//{
//	scanf("%d%d",&n,&m);
//	for (int i = 1; i <= n; i++) {
//		scanf("%d%d%d", &v, &w, &t);
//		for (int j = 0; j < v; j++) {
//			int k = 0, l = 1;
//			for (int p = j, x = 1; p <= m; p += v, ++x) {
//				int e = f[p] - x * w, r = x + t;
//				for (; k >= l && c[k][0] <= e; --k);
//				c[++k][0] = e; c[k][1] = r;
//				f[p] = c[l][0] + x * w;
//				for (; k >= l && c[l][1] == x; ++l);
//			}
//		}
//	}
//
//	printf("%d\n",f[m]);
//
//	return 0;
//}

int n, m;

const int N = 20010;
int dp[N];
int cpdp[N];

int q[N];

int main() {
	//cin >> n >> m;
	scanf("%d%d",&n,&m);
	for (int i = 1; i <= n; i++) {
		memcpy(cpdp,dp,sizeof dp);
		int v, w, s;
		//cin >> v >> w >> s;
		scanf("%d%d%d",&v,&w,&s);

		for (int j = 0; j < v; j++) {
			int hh = 0, tt = -1;
			for (int k = j; k <= m; k += v) {
				if (hh <= tt && q[hh] < k - s * v) hh++;
				while (hh <= tt && cpdp[q[tt]] + (k - q[tt]) / v * w <= cpdp[k]) tt--;
				q[++tt] = k;
				dp[k] = max(dp[k], cpdp[q[hh]] + (k - q[hh]) / v * w);
			}
		}
	}


	cout << dp[m] << endl;
}

/*
#include <iostream>
#include <memory.h>
#include <algorithm>

using namespace std;


const int N = 20010;
int dp[2][N];
int cpdp[2][N];
int n, m, v, w, s;

int q[N];

int curr = 1; int pre = 0;

int main()
{
	cin >> n >> m;

	for (int i = 1; i <= n; i++) {
		memcpy(cpdp,dp,sizeof dp);
		cin >> v >> w >> s;
		for (int j = 0; j < v; j++) {
			int hh = 0,tt = -1;
			for (int k = j; k <= m; k += v) {
				if (hh <= tt &&  q[hh] < k-s * v) {
					hh++;
				}
				while (hh <= tt && (cpdp[pre][q[tt]] + (k - q[tt]) / v * w) <= cpdp[pre][k])
					tt--;
				q[++tt] = k;
				dp[curr][k] = max(dp[curr][k], cpdp[pre][q[hh]] + (k - q[hh]) / v * w);
			}
		}
		swap(curr, pre);
	}

	cout << dp[pre][m] << endl;

	return 0;
}
*/